package com.zqh.template.filter;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.zqh.meta.Meta;
import lombok.var;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Distinct {


    /**
     * @description: 文件去重 同分组文件合并，不同分组保留
     * @return: java.util.List<com.zqh.meta.Meta.FileConfig.FilesInfo>
     */
    public static List<Meta.FileConfig.FilesInfo> distinctFiles(List<Meta.FileConfig.FilesInfo> filesInfoList) {


        // 1、有分组的，以组为单位划分
        Map<String, List<Meta.FileConfig.FilesInfo>> groupKeyFilesInfoListMap = filesInfoList
                .stream()
                .filter(o -> StrUtil.isNotEmpty(o.getGroupKey())) // 分组不为空的
                .collect(
                        Collectors.groupingBy(o -> o.getGroupKey())
                );

        // 2、 同分组内的配置合并
        // 创建一个Map，用于保存每个分组合并后的文件配置信息，键为分组键，值为合并后的FilesInfo对象
        Map<String, Meta.FileConfig.FilesInfo> groupKeyMergeFilesInfoMap = new HashMap<>();
        // 遍历分组键和对应FilesInfo列表的Map，处理每个分组
        for (var entry : groupKeyFilesInfoListMap.entrySet()) {
            // 获取当前分组的所有FilesInfo配置列表
            List<Meta.FileConfig.FilesInfo> temFilesInfoList = entry.getValue();
            // 合并处理FilesInfo中的文件列表：
            // 1. 使用流将多个FilesInfo中的files列表扁平化为单个流
            // 2. 根据inputPath去重，若重复则保留最后出现的文件
            // 3. 将去重后的值收集为新的文件列表
            var newFileInfoList = new ArrayList<Meta.FileConfig.FilesInfo>(
                    temFilesInfoList.stream()
                            .flatMap(filesInfo -> filesInfo.getFiles().stream())
                            .collect(
                                    Collectors.toMap(
                                            // InputPath作为键
                                            o -> o.getOutputPath(),
                                            // 对象全部作为值
                                            o -> o,
                                            // 有相同的键保留新的键
                                            (e, r) -> r
                                    )
                            ).values()
            );

            // 创建新的FilesInfo配置：
            // 使用当前分组最后一个FilesInfo配置作为基础（保留group、type等元数据）
            Meta.FileConfig.FilesInfo newFilesInfo = temFilesInfoList.get(0);
            // 替换原始文件列表为合并去重后的新列表
            newFilesInfo.setFiles(newFileInfoList);
            // 将合并后的配置放入结果Map
            String groupKey = entry.getKey();
            groupKeyMergeFilesInfoMap.put(groupKey, newFilesInfo);

        }
        // 3、讲文件分组添加到结果列表
        var resultList = new ArrayList<>(groupKeyMergeFilesInfoMap.values());

        // 4、将为分组的添加到结果列表
        List<Meta.FileConfig.FilesInfo> noGroupFilesInfoList = filesInfoList
                .stream()
                .filter(o -> StrUtil.isBlank(o.getGroupKey()))
                .collect(
                        Collectors.toList()
                );
        resultList.addAll(new ArrayList<>(noGroupFilesInfoList
                        .stream()
                        .collect(
                                Collectors.toMap(
                                        o -> o.getInputPath(),
                                        o -> o,
                                        (e, r) -> r
                                )
                        ).values()

                )
        );
        return resultList;
    }


    /*
     * @description: 模型去重 同分组的合并，不同分组保留
     * @params: [modelsInfoList]
     * @return: java.util.List<com.zqh.meta.Meta.ModelConfig.ModelsInfo>
     * @author: zqh
     * @dateTime: 2025/2/23 17:48
     */
    public static List<Meta.ModelConfig.ModelsInfo> distinctModels(List<Meta.ModelConfig.ModelsInfo> modelsInfoList) {

        // 1、有分组，以组为单位划分
        var groupKeyModelInfoListMap = modelsInfoList
                .stream()
                .filter(o -> StrUtil.isNotBlank(o.getGroupKey()))
                .collect(
                        Collectors.groupingBy(o -> o.getGroupKey())
                );

        // 2、同组内配置合并
        // 定义收集的哈希表
        var groupKeyMergeModelInfoMap = new HashMap<String, Meta.ModelConfig.ModelsInfo>();
        // 遍历哈希表集合
        for (var entry : groupKeyModelInfoListMap.entrySet()) {
            var temModelInfoList = entry.getValue();
            var newModelInfoList = new ArrayList<>(temModelInfoList.stream()
                    .flatMap(o -> o.getModels().stream())
                    .collect(
                            Collectors.toMap(
                                    o -> o.getFieldName(),
                                    o -> o,
                                    (e, r) -> r
                            )
                    ).values()
            );

            Meta.ModelConfig.ModelsInfo newModelInfo = CollUtil.getLast(temModelInfoList);
            newModelInfo.setModels(newModelInfoList);
            var groupKey = entry.getKey();
            groupKeyMergeModelInfoMap.put(groupKey, newModelInfo);
        }

        // 3、 将模型分组添加到结果列表
        List<Meta.ModelConfig.ModelsInfo> resultList = new ArrayList<>(groupKeyMergeModelInfoMap.values());

        // 4、将为分组的添加到结果列表
        var noGroupModelInfoList = modelsInfoList
                .stream()
                .filter(o -> StrUtil.isBlank(o.getGroupKey()))
                .collect(Collectors.toList());
        resultList.addAll(new ArrayList<>(noGroupModelInfoList.stream()
                .collect(Collectors.toMap(
                                o -> o.getFieldName(),
                                o -> o,
                                (e, r) -> r
                        )
                )
                .values()
        ));

        return resultList;
    }


}
